<template>
    <div class="console-page">
        <el-form inline :model="searchForm" class="e-page form-item forbid-select" spellcheck="false"
            @submit.native.prevent>
            <el-row class="toolbar">
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="searchForm.name" placeholder="仓库名称" clearable class="input-auto-resize" />
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-select v-model="searchForm.type" class="input-auto-resize" clearable popper-class="normal-poper"
                        placeholder="请选择仓库类型">
                        <el-option :label="item" :value="item"
                            v-for="(item, index) in tableData.map(e => e.type).filter((item, index, array) => array.indexOf(item) === index)"
                            :key="index" />
                    </el-select>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-select v-model="searchForm.format" class="input-auto-resize" clearable
                        popper-class="normal-poper" placeholder="请选择仓库格式">
                        <el-option :label="item" :value="item"
                            v-for="(item, index) in tableData.map(e => e.format).filter((item, index, array) => array.indexOf(item) === index)"
                            :key="index" />
                    </el-select>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-button type="primary" @click="search" circle class="button-auto-resize"
                        :icon="getIcon('search')" native-type="submit" />
                </el-col>
            </el-row>
        </el-form>
        <el-table :data="showData" border header-cell-class-name="el-table-header-cell" cell-class-name="el-table-cell"
            class="e-page table-without-pagination" highlight-current-row>
            <el-table-column prop="name" label="名称" width="300" />
            <el-table-column prop="type" label="类型" width="200" />
            <el-table-column prop="format" label="格式" width="200" />
            <el-table-column prop="status" label="状态" width="200">
                <template #default="scope">
                    <el-tag :type="scope.row.online ? 'success' : 'danger'" class="button-auto-resize"
                        disable-transitions>
                        {{ scope.row.online ? 'Online' : 'Offline' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="url" label="地址" min-width="400" />
            <el-table-column fixed="right" label="操作" :width="operationWidth" className="operation-column">
                <template #default="scope">
                    <el-button circle class="button-auto-resize" @click="getDetail(scope.row)" :icon="getIcon('Menu')"
                        type="primary" />
                    <el-button circle class="button-auto-resize" @click="" :icon="getIcon('Setting')" type="warning" />
                </template>
            </el-table-column>
        </el-table>

        <el-drawer v-model="showDrawer" direction="rtl" :show-close="false" @open="useModalSize" append-to-body
            :close-on-press-escape="false" size="90%" @closed="closeDrawer">
            <template #header>
                <el-form inline :model="repositorySearchForm" class="e-page form-item forbid-select" spellcheck="false"
                    @submit.native.prevent>
                    <el-row class="toolbar">
                        <el-col :span="4" style="padding-right: 5px">
                            <el-input v-model="repositorySearchForm.q" placeholder="KeyWords" clearable
                                class="input-auto-resize" />
                        </el-col>
                        <el-col :span="4" style="padding-right: 5px">
                            <el-input v-model="repositorySearchForm.name"
                                :placeholder="fieldMap[repositorySearchForm.format]?.name || fieldMap['default']?.name"
                                clearable class="input-auto-resize" />
                        </el-col>
                        <el-col :span="4" style="padding-right: 5px">
                            <el-select v-model="repositorySearchForm.repository" class="input-auto-resize" clearable
                                popper-class="normal-poper" placeholder="Repository">
                                <el-option :label="item.name" :value="item.name" :key="index"
                                    v-for="(item, index) in repositorySelect" />
                            </el-select>
                        </el-col>
                        <el-col :span="4" style="padding-right: 5px">
                            <el-input v-model="repositorySearchForm.group"
                                :placeholder="fieldMap[repositorySearchForm.format]?.group || fieldMap['default']?.group"
                                clearable class="input-auto-resize" />
                        </el-col>
                        <el-col :span="4" style="padding-right: 5px">
                            <el-input v-model="repositorySearchForm.version" placeholder="Version" clearable
                                class="input-auto-resize" />
                        </el-col>
                        <el-col :span="4" style="padding-right: 5px">
                            <el-button type="primary" @click="searchInRepository" circle class="button-auto-resize"
                                :icon="getIcon('search')" native-type="submit" />
                        </el-col>
                    </el-row>
                </el-form>
            </template>
            <div class="repository-detail-header forbid-select no-wrap">
                <span class="repository-detail-title no-wrap" style="width: calc(calc(100% - 700px)*.4)">
                    {{ fieldMap[repositorySearchForm.format]?.name || fieldMap['default']?.name }}
                </span>
                <span class="repository-detail-title no-wrap" style="width: calc(calc(100% - 700px)*.6);">
                    {{ fieldMap[repositorySearchForm.format]?.group || fieldMap['default']?.group }}
                </span>
                <span class="repository-detail-title no-wrap" style="width: 200px;">Version</span>
                <span class="repository-detail-title no-wrap" style="width: 200px;">Repository</span>
                <span class="repository-detail-title no-wrap" style="width: 200px;">LastUpdated</span>
                <span class="repository-detail-title no-wrap" style="width: 100px;">操作</span>
            </div>

            <el-scrollbar class="search-result" style="height: calc(100% - 50px);" ref="scrollbarRef">
                <div class="repository-detail-value-content" v-for="item in repositoryData">
                    <div :class="`repository-detail-value forbid-select no-wrap c-${item.id}`"
                        @click="showDetail(item)">
                        <span class="repository-detail-item " style="width: calc(calc(100% - 700px)*.4)">
                            <div class="no-wrap repository-detail-item-cell">
                                {{ item.name }}
                            </div>
                        </span>
                        <span class="repository-detail-item no-wrap" style="width: calc(calc(100% - 700px)*.6);">
                            <div class="no-wrap repository-detail-item-cell">
                                {{ item.group || '--' }}
                            </div>
                        </span>
                        <span class="repository-detail-item no-wrap" style="width: 200px;">
                            <div class="no-wrap repository-detail-item-cell">
                                {{ item.version }}
                            </div>
                        </span>
                        <span class="repository-detail-item no-wrap" style="width: 200px;">
                            <div class="no-wrap repository-detail-item-cell">
                                {{ item.repository }}
                            </div>
                        </span>
                        <span class="repository-detail-item no-wrap" style="width: 200px;">
                            <div class="no-wrap repository-detail-item-cell">
                                {{ item.lastUpdated }}
                            </div>
                        </span>
                        <span class="repository-detail-item no-wrap" style="width: 100px;">
                            <span style="padding: 5px 10px;">
                                <el-button link @click.stop.prevent="deleteComponent(item)" text
                                    style="font-family: inherit;color:red">删除组件</el-button>
                            </span>
                        </span>
                    </div>
                    <div v-if="item.open" :class="`component-detail v-${item.id}`">
                        <el-table :data="item.assets" header-cell-class-name="el-table-header-cell"
                            cell-class-name="el-table-cell" highlight-current-row class="forbid-select component-table">
                            <el-table-column label="Name" prop="name" min-width="300">
                                <template #default="scope">
                                    <div class="flex-display-center">
                                        <div @click="download(scope.row.checksum.sha1)" class="filename cursor-pointer">
                                            {{ scope.row.name }}
                                        </div>
                                    </div>
                                </template>
                            </el-table-column>
                            <el-table-column label="Content Type" prop="contentType" min-width="250" />
                            <el-table-column label="File Size" prop="fileSize" min-width="150">
                                <template #default="scope">
                                    {{ formatSize(scope.row.fileSize) }}
                                </template>
                            </el-table-column>
                            <el-table-column label="extension" prop="maven2.extension" v-if="item.format === 'maven2'"
                                min-width="180">
                                <template #default="scope">
                                    <span>{{ scope.row.maven2.extension }}</span>
                                    <span v-if="scope.row.maven2.classifier"> ({{ scope.row.maven2.classifier }})</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="lastModified" prop="lastModified" min-width="180">
                                <template #default="scope">
                                    <span>{{ new Date(scope.row.lastModified).format("YYYY-MM-DD HH:mm:ss") }}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作" width="140px">
                                <template #default="scope">
                                    <el-button link @click.stop.prevent="deleteComponentAsset(item, scope.row)" text
                                        style="font-family: inherit;color:red">删除组件资源</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </div>
                </div>
            </el-scrollbar>
        </el-drawer>
    </div>
</template>

<script setup>
import { useRequest, useSetTableOperationWidth, useModalSize, useElMessageBox, useElLoading } from "@usehook"
import { getIcon, formatSize } from "@/utils/tools"
import { baseUrl } from "@/utils/constant"

let tableData = $ref([])
let repositoryData = $ref([])
const operationWidth = useSetTableOperationWidth(2)
let showDrawer = $ref(false)
let currentRepository = $ref("")
let searchForm = $ref({})
let repositorySearchForm = $ref({ sort: "", direction: "", q: "", repository: "", format: "", group: "", name: "", version: "" })
let showData = $ref([])
let scrollbarRef = $ref(null)
const fieldMap = { maven2: { name: "Artifact Id", group: "Group Id" }, default: { name: "Name", group: "Group" } }
const repositorySelect = computed(() => tableData.map(e => { return { name: e.name, format: e.format } })
    .filter((item, index, array) => array.indexOf(item) === index && item.format === repositorySearchForm.format))

function matchesSearch(item, search) {
    // 遍历搜索对象的每个属性
    for (let key in search) {
        // 如果搜索对象的属性在item中不存在，或者值不相等，则返回false
        if (search[key] !== undefined && !item[key]?.includes(search[key])) {
            return false
        }
    }
    // 如果所有搜索条件都匹配，则返回true
    return true
}

const search = () => {
    showData = tableData.filter(item => matchesSearch(item, searchForm))
}

const deleteComponent = (item) => {
    useElMessageBox("确认删除该组件?", () => h("div", {}, [
        h("div", { class: "confirm-line" }, [h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Artifact Id:"), h("span", { class: "confirm-value no-wrap" }, item.name)]),
        h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Group Id:"), h("span", { class: "confirm-value no-wrap", style: { width: "fit-content" } }, item.group)])]),

        h("div", { class: "confirm-line" }, [h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Version:"), h("span", { class: "confirm-value no-wrap" }, item.version)]),
        h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Repository:"), h("span", { class: "confirm-value no-wrap" }, item.repository)])])
    ]), { showCancelButton: true, showIcon: false }).then(() => {
        const loading = useElLoading("正在删除组件")
        useRequest.post("/mvn/component/remove/" + item.id).then(resp => {
            if (resp && resp.status) {
                repositoryData.splice(repositoryData.findIndex(t => t.id === item.id), 1)
            }
        }).finally(() => loading.close())
    })
}

const deleteComponentAsset = (item, asset) => {
    useElMessageBox("确认删除该组件资源?", () => h("div", {}, [
        h("div", { class: "confirm-line" }, [h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Artifact Id:"), h("span", { class: "confirm-value no-wrap" }, item.name)]),
        h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Group Id:"), h("span", { class: "confirm-value no-wrap", style: { width: "fit-content" } }, item.group)])]),

        h("div", { class: "confirm-line" }, [h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Version:"), h("span", { class: "confirm-value no-wrap" }, item.version)]),
        h("span", { class: "confirm-item" }, [h("span", { class: "confirm-title" }, "Repository:"), h("span", { class: "confirm-value no-wrap" }, item.repository)])]),
        h("div", { class: "confirm-line" }, [h("span", { class: "confirm-title" }, "Path:"), h("span", { style: { color: "brown" } }, asset.path)])
    ]), { showCancelButton: true, showIcon: false }).then(() => {
        const loading = useElLoading("正在删除组件资源")
        useRequest.post("/mvn/asset/remove/" + asset.id).then(resp => {
            if (resp && resp.status) {
                item.assets.splice(item.assets.findIndex(t => t.id === asset.id), 1)
                document.querySelector(".v-" + item.id).style.height = "calc(var(--font-size)* 2.5 *" + (item.assets.length + 1) + ")"
            }
        }).finally(() => loading.close())
    })
}

const updateScrollbar = () => {
    // 更新scrollbar滚动条状态
    nextTick(() => scrollbarRef.update())
}

const showDetail = (item) => {
    // 先关闭其他所有的打开状态
    for (let i of repositoryData) {
        if (item.id === i.id) continue
        document.querySelector(".c-" + i.id).style.background = "none"
        if (i.open) {
            document.querySelector(".v-" + i.id).style.height = "0"
            updateScrollbar()
            // timeout写在每个对象上，避免单独维护
            clearTimeout(i.timeout)
            i.timeout = setTimeout(() => {
                i.open = false
                i.isOpen = false
                updateScrollbar()
            }, 500)
        }
    }
    //临时变量保存打开状态
    item.isOpen = !item.isOpen
    // 临时状态打开时更新open状态
    if (item.isOpen) {
        item.open = item.isOpen
        updateScrollbar()
    }
    // 调整高度和背景色
    nextTick(() => {
        if (item.open) document.querySelector(".v-" + item.id).style.height = item.isOpen ? "calc(var(--font-size)* 3 *" + (item.assets.length + 1) + ")" : "0"
        updateScrollbar()
        document.querySelector(".c-" + item.id).style.background = item.isOpen ? "#ffb3b3" : "none"
    })
    clearTimeout(item.timeout)
    item.timeout = setTimeout(() => {
        item.open = item.isOpen
        updateScrollbar()
    }, 500)
}

const closeDrawer = () => {
    useModalSize(false)
    repositoryData = []
    currentRepository = ""
    repositorySearchForm = { sort: "", direction: "", q: "", repository: "", format: "", group: "", name: "", version: "" }
}

const filterRepositorySearchForm = () => {
    return Object.fromEntries(
        Object.entries(repositorySearchForm).filter(([, value]) => {
            // 在这里添加你的非空检查逻辑
            return value !== null && value !== undefined && value !== ''
        })
    )
}

const getDetail = (row) => {
    currentRepository = row.name
    const loading = useElLoading("正在加载" + currentRepository + "仓库资源")
    repositorySearchForm.repository = row.name
    repositorySearchForm.format = row.format
    useRequest("/mvn/repository/list", filterRepositorySearchForm()).then(resp => {
        if (resp && resp.status) {
            repositoryData = resp.data
            for (let item of resp.data) {
                item.lastUpdated = new Date(Math.max(...item.assets.map(e => new Date(e.lastModified).getTime()))).format('YYYY-MM-DD HH:mm:ss')
            }
            showDrawer = true
        }
    }).finally(() => loading.close())
}

const download = sha1 => {
    let link = document.createElement('a')
    link.target = "_blank"
    link.href = baseUrl + "/mvn/assets/download/" + sha1
    link.click()
    link.remove()
}

const searchInRepository = () => {
    const loading = useElLoading("正在加载" + currentRepository + "仓库资源")
    useRequest("/mvn/repository/list", filterRepositorySearchForm()).then(resp => {
        if (resp && resp.status) {
            repositoryData = resp.data
            for (let item of resp.data) {
                item.lastUpdated = new Date(Math.max(...item.assets.map(e => new Date(e.lastModified).getTime()))).format('YYYY-MM-DD HH:mm:ss')
            }
        }
    }).finally(() => loading.close())
}

onMounted(() => {
    const loading = useElLoading("正在加载" + currentRepository + "仓库资源")
    useRequest("/mvn/repositories", {}).then(resp => {
        if (resp && resp.status) {
            resp.data.sort((a, b) => {
                if (a.format !== b.format) {
                    return a.format < b.format ? -1 : 1;
                } else if (a.name !== b.name) {
                    return a.name < b.name ? -1 : 1;
                } else {
                    return a.city < b.city ? -1 : 1;
                }
            })
            showData = tableData = resp.data
        }
    }).finally(() => loading.close())
})

</script>

<style>
.repository-detail .el-table__expanded-cell {
    background: transparent;
}

.repository-detail-title {
    display: inline-block;
    text-align: center;
}

.repository-detail-item {
    display: inline-block;
    text-align: center;
    height: 100%;
}

.repository-detail-item-cell {
    padding: 10px;
    height: 40px;
    line-height: 40px;
}

.repository-detail-header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    background: rgba(185, 185, 185, .5);
    color: #909399;
}

.repository-detail-value {
    height: 60px;
    line-height: 60px;
    font-size: 16px;
    box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
    transition: background .5s;
}

.repository-detail-value-content:hover {
    background: rgb(149 190 255 / .1);
}

.component-detail {
    will-change: height;
    transition: height .5s;
    height: 0;
    overflow: hidden;
    background: rgb(255 250 240 / 60%);
}

.confirm-title {
    width: 100px;
    display: inline-block;
    padding-right: 10px;
    text-align: right;
}

.confirm-item {
    display: inline-flex;
}

.confirm-line {
    height: 30px;
    line-height: 30px;
}

.confirm-value {
    width: 150px;
    display: inline-block;
    color: brown;
}

.component-detail .filename {
    width: fit-content;
    text-decoration-line: underline;
    color: blue
}

.search-result .el-scrollbar__thumb {
    transition: height .5s;
}

.component-table.el-table .el-table__cell {
    border: none !important;
}

.component-table.el-table .el-table__row,
.component-table.el-table .el-table__header {
    height: calc(var(--font-size)* 3) !important;
}

.component-table.el-table .el-table__row {
    box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
}
</style>